#ifndef CLUTILS_H
#define	CLUTILS_H

#include <CL/cl.h>
#include "FormatString.h"
#include "Exceptions.h"
#include <string>
#include <vector>

#define CL_CHECK(result) checkError(result, __FILE__, __LINE__)
#define ASSERT(condition, message) assertTrue(condition, message, __FILE__, __LINE__)
#define SHOULDNT_REACH() ASSERT(false, "Should never reach ")

const std::string errorCodeToMessage(cl_int code);

void checkError(cl_int result, const char* file, int line);

inline void assertTrue(bool condition, const char* message, const char* file, int line) {
    if (!condition) {
        throw Exception(FormatString() << message << " at " << file << " line " << line);
    }
}

cl_program buildProgram(cl_context context, cl_device_id device, const char* sources);
cl_program buildProgramFromFile(cl_context context, cl_device_id deviceId, const char* fileName);

cl_command_queue createQueue(cl_device_id deviceId, cl_command_queue_properties flags);
cl_context getContext(cl_command_queue q);
cl_device_id getDeviceId(cl_command_queue q);
void enumOpenCLDevices(std::vector<cl_device_id> &output, cl_device_type deviceType);

template <typename T>
inline T select(T a, T b, int expr) {
	return expr ? b : a;
}

#endif	/* CLUTILS_H */

